package com.party.admin.web.controller.logistics;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.party.admin.biz.logistics.WlLogisticsBizService;
import com.party.admin.biz.mall.MallOrderBizService;
import com.party.admin.jms.publisher.service.IMallAutoCompletePubulisherService;
import com.party.admin.utils.excel.ImportExcel;
import com.party.admin.web.dto.AjaxResult;
import com.party.common.utils.DateUtils;
import com.party.common.utils.StringUtils;
import com.party.core.model.logistics.*;
import com.party.core.model.mall.MallOrderDetail;
import com.party.core.service.logistics.IWlExpressService;
import com.party.core.service.logistics.IWlParcelService;
import com.party.core.service.logistics.biz.LogisticsBizService;
import com.party.core.service.mall.IMallOrderDetailService;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Row;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

/**
 * 物流控制器
 * Created by yifeng
 *
 * @date 2018/4/23 0023
 * @time 下午 16:12
 */
@Controller
@RequestMapping("/logistics/logistics")
public class LogisticsController {
    @Autowired
    private LogisticsBizService logisticsBizService;
    @Autowired
    private MallOrderBizService mallOrderBizService;
    @Autowired
    private IWlParcelService wlParcelService;
    @Autowired
    private IWlExpressService wlExpressService;
    @Autowired
    private IMallOrderDetailService mallOrderDetailService;
    @Autowired
    private WlLogisticsBizService wlLogisticsBizService;
    @Autowired
    private IMallAutoCompletePubulisherService mallAutoCompletePubulisherService;

    @Value("#{kuaidiniao['kuaidiniao.eBusinessID']}")
    private String eBusinessID;
    @Value("#{kuaidiniao['kuaidiniao.apiKey']}")
    private String apiKey;

    Logger logger = LoggerFactory.getLogger(getClass());


    /**
     * 商品发货
     *
     * @param shipmentInput 发货参数
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "doShipment", method = RequestMethod.POST)
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public AjaxResult doShipment(ShipmentInput shipmentInput) {
        try {
            if (StringUtils.isEmpty(shipmentInput.getTargetId()) || StringUtils.isEmpty(shipmentInput.getGoodsTargetIds())) {
                return AjaxResult.error("业务id不能为空");
            }
            if (shipmentInput.getType().equals(WlTargetType.MALL.getCode())) {
                mallOrderBizService.updateShipmentStatus(shipmentInput.getTargetId(), shipmentInput.getGoodsTargetIds());
            }
            WlLogistics logistics = logisticsBizService.doShipmentInsert(shipmentInput);
            logisticsBizService.subscribe(logistics, shipmentInput.getTargetId(), apiKey, eBusinessID);
            return AjaxResult.success();
        } catch (Exception e) {
            logger.error("发货异常", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("发货异常");
        }
    }

    /**
     * 查看发货信息
     *
     * @param targetId 业务id
     * @return
     */
    @ResponseBody
    @RequestMapping("searchShipment")
    public AjaxResult searchShipment(String targetId) {
        Map<String, Object> result = Maps.newHashMap();

        List<WlParcelOutput> parcels = wlParcelService.findByTargetId(targetId);
        result.put("parcels", parcels);

        List<WlExpress> mallExpresses = wlExpressService.getAllExpress();
        result.put("couriers", mallExpresses);
        return AjaxResult.success(result);
    }

    /**
     * 修改发货信息
     *
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "updateShipment", method = RequestMethod.POST)
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public AjaxResult updateShipment(ShipmentInput shipmentInput) {
        try {
            logisticsBizService.updateShipment(shipmentInput.getParcels(), apiKey, eBusinessID);
            return AjaxResult.success();
        } catch (Exception e) {
            logger.error("修改发货异常", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("修改发货信息异常");
        }
    }

    /**
     * 修改礼包发货信息
     *
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "updateGiftShipment", method = RequestMethod.POST)
    public AjaxResult updateGiftShipment(ShipmentInput shipmentInput) {
        try {
            if (StringUtils.isEmpty(shipmentInput.getLogisticsId())) {
                return AjaxResult.error("物流编号不能为空");
            }
            logisticsBizService.updateGiftShipment(shipmentInput);
            return AjaxResult.success();
        } catch (Exception e) {
            logger.error("修改发货异常", e);
            return AjaxResult.error("修改发货信息异常");
        }
    }

    @ResponseBody
    @RequestMapping("importExpress")
    public AjaxResult importExpress() {
        try {
            ImportExcel ei = new ImportExcel("F:/ExpressCode.xls", 1);
            for (int i = ei.getDataRowNum(); i < ei.getLastDataRowNum(); i++) {
                Row row = ei.getRow(i);
                Object code = ImportExcel.getCellValue(row, 0);
                Object name = ImportExcel.getCellValue(row, 1);
                WlExpress mallExpress = new WlExpress();
                mallExpress.setCode(name.toString());
                mallExpress.setName(code.toString());
                wlExpressService.insert(mallExpress);
            }
        } catch (InvalidFormatException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return AjaxResult.success();
    }

    /**
     * 订阅推送回调
     *
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping("logisticsNotify")
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void logisticsNotify(HttpServletRequest request, HttpServletResponse httpServletResponse) throws IOException {
        String requestData = request.getParameter("RequestData");
        String requestType = request.getParameter("RequestType");
        String dataSign = request.getParameter("DataSign");
        logger.error("订阅推送参数----requestData:{},requestType:{},dataSign:{}", requestData, requestType, dataSign);
        logger.error("接收到轨迹订阅推送数据：{}，{}", DateUtils.formatDate(new Date()), requestData);

        Map<String, Object> result = Maps.newHashMap();
        result.put("EBusinessID", eBusinessID);
        result.put("UpdateTime", DateUtils.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
        result.put("Success", true);
        httpServletResponse.getWriter().write(JSONObject.toJSONString(result));
        httpServletResponse.getWriter().close();

        try {
            wlLogisticsBizService.saveNotifyData(requestData, new Function<String, Object>() {

                @Override
                public Object apply(String orderId) {
                    mallAutoCompletePubulisherService.sendMessage(orderId);
                    return null;
                }
            });
        } catch (Exception e) {
            logger.error("物流推送接收异常：requestData=" + requestData, e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

    /**
     * 根据物流id获取物流追踪信息
     *
     * @param logisticsId 物流id
     * @return
     */
    @RequestMapping("findLogisticsById")
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public ModelAndView findLogisticsById(String logisticsId) {
        ModelAndView mv = new ModelAndView("/mall/order/traceList");
        try {
            WlParcelOutput parcelOutput = new WlParcelOutput();
            parcelOutput.setLogisticsId(logisticsId);
            List<WlLogisticsTrace> logisticsTraces = logisticsBizService.getLogisticsTraces(parcelOutput, apiKey, eBusinessID);
            mv.addObject("traces", logisticsTraces);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return mv;
    }


    /**
     * 跳转到礼包发货页面
     *
     * @param targetId 领取订单ID
     * @return
     */
    @RequestMapping("giftShipments")
    public ModelAndView giftShipments(String targetId) {
        ModelAndView mv = new ModelAndView("/gift/shipments");
        List<WlExpress> mallExpresses = wlExpressService.getAllExpress();
        mv.addObject("couriers", mallExpresses);
        WlParcelOutput parcelOut = logisticsBizService.getParcelByTargetId(targetId);
        mv.addObject("parcelOut", parcelOut);
        mv.addObject("targetId", targetId);
        return mv;
    }

    /**
     * 快递公司redis刷新
     *
     * @return
     */
    @ResponseBody
    @RequestMapping("refreshExpressRedis")
    public AjaxResult refreshExpressRedis() {
        wlExpressService.pushRedis();
        return AjaxResult.success();
    }

    /**
     * 初始化包裹的targetId为主订单的order_id
     *
     * @return
     */
    @ResponseBody
    @RequestMapping("initParcelData")
    public AjaxResult initParcelData() {
        List<WlParcel> wlParcels = wlParcelService.list(new WlParcel());
        for (WlParcel wlParcel : wlParcels) {
            if (wlParcel.getType().equals(WlTargetType.MALL.getCode())) {
                MallOrderDetail orderDetail = mallOrderDetailService.get(wlParcel.getTargetId());
                wlParcel.setTargetId(orderDetail.getOrderId());
                wlParcelService.update(wlParcel);
            }
        }
        return AjaxResult.success();
    }
}
